import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.jfree.io.IOUtils;

import weka.core.PropertyPath.Path;


public class NetKitSRL {

	private static HashMap<String, Integer> labelCount = new HashMap<String, Integer>();
	private static HashMap<String, Integer> labelEdgeCount = new HashMap<String, Integer>();
	private static HashMap<String, Integer> vertexEdgeCount = new HashMap<String, Integer>();
	private static HashMap<String, ArrayList<Integer>> listAllVerticesByLabel = new HashMap<String, ArrayList<Integer>>();
	
	private static HashMap<String, String> vertexList = new HashMap<String, String>();
	private static final String delimiter = ",";
	private static boolean isWebKB = true;
	
	private static String dataPath = "";
	private static HashMap<String, String> dataPathMap = new HashMap<String, String>();
	
	public static void main(String[] args) throws IOException {
		GUIMagic();
	}

	private static void runDataAnalysis() throws IOException {
		
        File sourceDirFile = new File(dataPathMap.get(dataPath));
        File csv = new File(sourceDirFile + System.getProperty("file.separator") + sourceDirFile.getName() + ".csv");
        File rn = new File(sourceDirFile + System.getProperty("file.separator") + sourceDirFile.getName() + ".rn");
        
        int numberOfFuckingVertices = 0;
        int numberOfFuckingEdges = 0;
        
        numberOfFuckingVertices = analyseVertices(csv, numberOfFuckingVertices);
        
        numberOfFuckingEdges = analyseEdges(rn, numberOfFuckingEdges);
        
        printResult(numberOfFuckingVertices, numberOfFuckingEdges);
       
        startNetKitAndPrintAUC(sourceDirFile);
	}

	private static void startNetKitAndPrintAUC(File sourceDirFile) throws IOException 
	{
		// Calc auc
        // Start jar file
 		Process p = Runtime.getRuntime().exec("java -jar \"" + System.getProperty("user.dir") 
 				+ System.getProperty("file.separator") + "data"
 			    + System.getProperty("file.separator") + "Session3"
 			    + System.getProperty("file.separator") + "netkit"
 			    + System.getProperty("file.separator") + "lib"
 			    + System.getProperty("file.separator") + "NetKit-1.3.0.jar\" -showAUC \"" + sourceDirFile 
 				+ System.getProperty("file.separator") + sourceDirFile.getName() + ".arff\"");
 		
 		BufferedReader inB = new BufferedReader(new InputStreamReader(p.getInputStream()));
 		BufferedReader errB = new BufferedReader(new InputStreamReader(p.getErrorStream()));
 		
 		try {
			Thread.currentThread().sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
 		
 		System.out.println("");
 		
 		String line = null;
 		while((line = inB.readLine()) != null) 
 		{
 			if (line.startsWith("AUC-") && line.contains("Final"))
 				System.out.println(line);
 		}
 		
 		System.out.println("");
 		
 		line = null;
 		while((line = errB.readLine()) != null) 
 		{
 			System.out.println(line);
 		}
 		
 		p.destroy();
	}

	private static int analyseEdges(File inputRNFilePath,	int numberOfFuckingEdges) throws IOException 
	{
		BufferedReader inputRN = new BufferedReader(new InputStreamReader(new FileInputStream(inputRNFilePath)));
		
		String edge = "";
        while( (edge = inputRN.readLine()) != null) 
        {
        	if (isWebKB)
        	{
        		int edgeWeight = Integer.valueOf(edge.split(delimiter)[2]);
        		numberOfFuckingEdges += edgeWeight;
        	}
        	else
        	{
        		numberOfFuckingEdges++;
        	}       	
        	
        	if (isWebKB)
        	{
	        	vertexEdgeCount.put(edge.split(delimiter)[0], vertexEdgeCount.get(edge.split(delimiter)[0]) + Integer.valueOf(edge.split(delimiter)[2]));
	        	vertexEdgeCount.put(edge.split(delimiter)[1], vertexEdgeCount.get(edge.split(delimiter)[1]) + Integer.valueOf(edge.split(delimiter)[2]));
        	}
        	else
        	{
        		vertexEdgeCount.put(edge.split(delimiter)[0], vertexEdgeCount.get(edge.split(delimiter)[0] + 1));
	        	vertexEdgeCount.put(edge.split(delimiter)[1], vertexEdgeCount.get(edge.split(delimiter)[1] + 1));
        	}
        	
        	String vertex1Label = vertexList.get(edge.split(delimiter)[0]);
        	String vertex2Label = vertexList.get(edge.split(delimiter)[1]);
        	
        	if (labelEdgeCount.containsKey(vertex1Label))
        	{
        		int currentLabel = labelEdgeCount.get(vertex1Label).intValue(); 
        		labelEdgeCount.put(vertex1Label, isWebKB ? currentLabel + Integer.valueOf(edge.split(delimiter)[2]) : ++currentLabel);
        	}
        	else
        	{
        		labelEdgeCount.put(vertex1Label, isWebKB ? Integer.valueOf(edge.split(delimiter)[2]) : 1);
        	}
        	
        	if (labelEdgeCount.containsKey(vertex2Label))
        	{
        		int currentLabel = labelEdgeCount.get(vertex2Label).intValue(); 
        		labelEdgeCount.put(vertex2Label, isWebKB ? currentLabel + Integer.valueOf(edge.split(delimiter)[2]) : ++currentLabel);
        	}
        	else
        	{
        		labelEdgeCount.put(vertex2Label, isWebKB ? Integer.valueOf(edge.split(delimiter)[2]) : 1);
        	}
        }    
        
        for (String vertexName : vertexEdgeCount.keySet()) 
        {
        	if (listAllVerticesByLabel.containsKey(vertexList.get(vertexName)))
        	{
        		listAllVerticesByLabel.get(vertexList.get(vertexName)).add(vertexEdgeCount.get(vertexName));
        	}
        	else
        	{
        		ArrayList<Integer> list = new ArrayList<Integer>();
        		list.add(vertexEdgeCount.get(vertexName));
        		listAllVerticesByLabel.put(vertexList.get(vertexName), list);
        	}
		}
        
        inputRN.close();
        
		return numberOfFuckingEdges;
	}

	private static int analyseVertices(File inputCSVFilePath, int numberOfFuckingVertices) throws IOException 
	{
		BufferedReader inputCSV = new BufferedReader(new InputStreamReader(new FileInputStream(inputCSVFilePath)));
		
		String vertex = "";
        while( (vertex = inputCSV.readLine()) != null) {
        	vertexList.put(vertex.split(delimiter)[0], vertex.split(delimiter)[1]);
        	
        	numberOfFuckingVertices++;
        	if (labelCount.containsKey(vertex.split(delimiter)[1]))
        	{
        		int currentLabel = labelCount.get(vertex.split(delimiter)[1]).intValue(); 
        		labelCount.put(vertex.split(delimiter)[1], ++currentLabel);
        	}
        	else
        	{
        		labelCount.put(vertex.split(delimiter)[1], 1);
        	}
        	
        	vertexEdgeCount.put(vertex.split(delimiter)[0], 0);
        }
        inputCSV.close();
        
		return numberOfFuckingVertices;
	}

	private static void printResult(int numberOfFuckingVertices, int numberOfFuckingEdges) 
	{
		System.out.println("No# vertices:" + numberOfFuckingVertices);
        System.out.println("No# edges:" + numberOfFuckingEdges);
        System.out.println("Density: " + numberOfFuckingEdges / numberOfFuckingVertices);
        
        System.out.println("");
        
        for (String key : labelCount.keySet()) 
        {
			System.out.println("Label: " + key + " Count: " + labelCount.get(key));
		}
        
        System.out.println("");
        
        for (String key : labelEdgeCount.keySet()) 
        {
			System.out.println("Edge Label: " + key + " Count: " + labelEdgeCount.get(key));
		}
        
        System.out.println("");
        
        for (String key : listAllVerticesByLabel.keySet()) 
        {
        	Collections.sort(listAllVerticesByLabel.get(key));
        	Collections.reverse(listAllVerticesByLabel.get(key));
        	int allEdgesWithCurrentLabel = labelEdgeCount.get(key);
        	int sumOfCountedEdges = 0;
        	int counterVertices = 0;
        	
        	do 
        	{
				sumOfCountedEdges += listAllVerticesByLabel.get(key).get(counterVertices);
				counterVertices++;
        		
			} while (sumOfCountedEdges < allEdgesWithCurrentLabel * 0.8);
        	
        	System.out.println(key + " : 80 percent of edges comes from " + (counterVertices * 100) / labelCount.get(key) + " percent of vertices");
        	
		}
	}

	private static void GUIMagic() 
	{
		
        String 	sourceDir = System.getProperty("user.dir") + "/data/Session3/";
        HashMap<String, String> dirMap = new HashMap<String, String>();
        
		File source = new File(sourceDir);
        for(File dir : source.listFiles()){
        	if(dir.listFiles() == null)
        		continue;
        	for(File dataset : dir.listFiles()){
        		if(dataset.listFiles() == null)
        			continue;
        		for(File file : dataset.listFiles()){
        			if(file.getName().endsWith(".arff")) {
        				dirMap.put( (new File(file.getParent())).getName() , file.getParent());
        			}
        		}
        	}
        }
        dataPathMap = new HashMap<String, String>(dirMap);
		
        JFrame myJFrame = new JFrame();
        myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myJFrame.setTitle("NetKitSRL");
        myJFrame.setSize(250, 150);
        JPanel panel = new JPanel();
        JLabel label = new JLabel("Choose your dataset below:");
        panel.add(label);
        String comboBoxList[] = dirMap.keySet().toArray(new String[0]);
        final JComboBox<String> datasetBox = new JComboBox<String>(comboBoxList);
        panel.add(datasetBox);
        JButton button = new JButton("Let's go!");
        button.addActionListener(null);
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
            	dataPath = (String) datasetBox.getSelectedItem();
				try {
					runDataAnalysis();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
            }
        });      
        panel.add(button);
        myJFrame.add(panel);
        myJFrame.setVisible(true);
	}
		
}